import { defineStore } from 'pinia';
import { BrowserGroups } from '@/components/deviceMaintenance';
import { ReadDataTaskExecutedResult } from '@/types/ReadDataTaskExecutedResult';
import * as signalR from '@microsoft/signalr';

class SignalRRetryPolicy implements signalR.IRetryPolicy {
  nextRetryDelayInMilliseconds(retryContext: signalR.RetryContext): number | null {
    return 10000; // 10 s
  }
}

export type ReadValueCallback = (result: ReadDataTaskExecutedResult) => void;

export const useDeviceMaintenanceSignalRClientStore = defineStore(
  'device-maintenance-signalr-client',
  () => {
    const url = import.meta.env.VITE_DEVICE_MAINTENANCE_BASE_URL + '/browser-hub';
    const connection = new signalR.HubConnectionBuilder()
      .withUrl(url)
      .withAutomaticReconnect(new SignalRRetryPolicy())
      .build();
    const maps = new Map<string, ReadValueCallback>();

    function isConnected() {
      return connection.state == signalR.HubConnectionState.Connected;
    }

    async function connectServerAsync() {
      await connection.start();
      connection?.on('OnReadValueAsync', (result: ReadDataTaskExecutedResult) => {
        maps.forEach((callback, key) => {
          if (key == result.partId) {
            callback(result);
          }
        });
      });
      await connection?.invoke('AddToGroup', BrowserGroups.DeviceMaintenance);
    }

    async function subscribeAsync(partId: string, callback: ReadValueCallback) {
      maps.set(partId, callback);
    }

    async function unsubscribeAsync(partId: string) {
      if (maps.has(partId)) {
        maps.delete(partId);
      }
    }

    return {
      isConnected,
      connectServerAsync,
      subscribeAsync,
      unsubscribeAsync
    };
  }
);
